/* 
 * Copyright 2011 kOSMik.
 * This file is part of kOSMik.
 * 
 * kOSMik is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * kOSMik is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with kOSMik.  If not, see <http://www.gnu.org/licenses/>.
 *  
 * kOSMik:
 * Open Street Map - Editor.
 * http://code.google.com/p/swp-dv-ws2010-osm-2/
 */

package de.fuberlin.kosmik.data.osmt;

/**
 * This abstract class represents a rudimentary record.
 * 
 * @author Johannes
 * @see OsmtNodeRecord
 * @see OsmtFeatureRecord
 * 
 * 
 */
public abstract class OsmtElementRecord {

	/**
	 * The attribute element specifies whether the element is a poi, a way and
	 * an area.
	 */
	public int elements = 0;
	/** url to an icon. */
	public String icon;
	/** a comment. */
	public String comment;
	/** how often was this elements used. */
	public int use;

	// flags to signal, in which elements a value can happen
	// used in nearly all Osmt* classes
	/** value to specify a node element. */
	public static final int ELEMENT_NODE = 1;
	/** value to specify a way element. */
	public static final int ELEMENT_WAY = 2;
	/** value to specify an area element. */
	public static final int ELEMENT_AREA = 4;
	/** value to specify a relation. */
	public static final int ELEMENT_RELATION = 8;
	/**
	 * Value to specify that an element is compatible to a node, way, area and
	 * relation etc.
	 */
	public static final int ELEMENT_ALL = ELEMENT_NODE | ELEMENT_WAY | ELEMENT_AREA
			| ELEMENT_RELATION;
	/** the default element value. */
	public static final int ELEMENT_DEFAULT = ELEMENT_ALL;

	/**
	 * Splits the given string that contains a set of elements in form
	 * "node/way/area" into the int representation.
	 * 
	 * @param elementString like "node/way/area"
	 * @return the integer representation
	 */
	public static int splitElementStringToInt(final String elementString) {
		int elements = 0;
		if (elementString != null) {
			String[] elementArray = elementString.split("/");
			for (String elem : elementArray) {
				if (elem.equals("node")) {
					elements |= ELEMENT_NODE;
				} else if (elem.equals("way")) {
					elements |= ELEMENT_WAY;
				} else if (elem.equals("area")) {
					elements |= ELEMENT_AREA;
				} else if (elem.equals("relation")) {
					elements |= ELEMENT_RELATION;
				}
			}
		}
		return elements;
	}

	/**
	 * Converts boolean elements into a integer equivalent.
	 * 
	 * @param isPoi is true if this element is applicable to a poi
	 * @param isWay is true if this element is applicable to a way
	 * @param isArea is true if this element is applicable to an area
	 * @return an integer that contain all passed informations
	 */
	public static int convertElementsToInt(final boolean isPoi, final boolean isWay,
			final boolean isArea) {
		int result = 0;
		if (isPoi) {
			result += ELEMENT_NODE;
		}
		if (isWay) {
			result += ELEMENT_WAY;
		}
		if (isArea) {
			result += ELEMENT_AREA;
		}

		return result;
	}

	/**
	 * Check, if the OsmtElementRecord-object is appreciable to a way.
	 * 
	 * @param osmtElementRecord The record to which should be checked.
	 * @return true, if the object is appreciable to a way, otherwise false
	 */
	public static boolean isWay(OsmtElementRecord osmtElementRecord) {
		return (osmtElementRecord.elements & ELEMENT_WAY) == ELEMENT_WAY;
	}

	/**
	 * Check, if the OsmtElementRecord-object is appreciable to an area.
	 * 
	 * @param osmtElementRecord The record to which should be checked.
	 * @return true, if the object is appreciable to an area, otherwise false
	 */
	public static boolean isArea(OsmtElementRecord osmtElementRecord) {
		return (osmtElementRecord.elements & ELEMENT_AREA) == ELEMENT_AREA;
	}

	/**
	 * Check, if the OsmtElementRecord-object is appreciable to a node.
	 * 
	 * @param osmtElementRecord The record to which should be checked.
	 * @return true, if the object is appreciable to a node, otherwise false
	 */
	public static boolean isNode(OsmtElementRecord osmtElementRecord) {
		return (osmtElementRecord.elements & ELEMENT_NODE) == ELEMENT_NODE;
	}

	/**
	 * Check, if the OsmtElementRecord-object is appreciable to a relation.
	 * 
	 * @param osmtElementRecord The record to which should be checked.
	 * @return true, if the object is appreciable to a relation, otherwise false
	 */
	public static boolean isRelation(OsmtElementRecord osmtElementRecord) {
		return (osmtElementRecord.elements & ELEMENT_RELATION) == ELEMENT_RELATION;
	}

	/**
	 * Check, if elements encodes a way.
	 * 
	 * @param elements The element set which should be checked.
	 * @return true, if elements contains a way, otherwise false
	 */
	public static boolean isWay(final int elements) {
		return (elements & ELEMENT_WAY) == ELEMENT_WAY;
	}

	/**
	 * Check, if elements encodes an area way.
	 * 
	 * @param elements The element set which should be checked.
	 * @return true, if elements contains an area, otherwise false
	 */
	public static boolean isArea(final int elements) {
		return (elements & ELEMENT_AREA) == ELEMENT_AREA;
	}

	/**
	 * Check, if elements encodes a node.
	 * 
	 * @param elements The element set which should be checked.
	 * @return true, if elements contains a node, otherwise false
	 */
	public static boolean isNode(final int elements) {
		return (elements & ELEMENT_NODE) == ELEMENT_NODE;
	}

	/**
	 * Check, if elements encodes a relation.
	 * 
	 * @param elements The element set which should be checked.
	 * @return true, if elements contains a relation, otherwise false
	 */
	public static boolean isRelation(final int elements) {
		return (elements & ELEMENT_RELATION) == ELEMENT_RELATION;
	}

}
